<?php
if (! defined ( 'IN_BIC' )) {
	die ( '非法View访问来源!' );
}
/**
 *
 * @package Bic
 * @author Bic
 * @version $Id: BicSqli.php 2010年5月11日 21时32分29秒
 * @copyright (c) 2010 Bic
 * @license http://opendebugurce.org/licenses/gpl-license.php GNU Public License
 *
 * Minimum Requirement: PHP 5.0.1
 */
class Bic_View extends Bic_View_Abstract {
    
    /**
     * 模板路径
     * @var unknown_type
     */
    public $_dir = null;
    /**
     * js、css、img等网站素材所在目录
     * @var unknown_type
     */
    public $_www = null;
    
    public $_layout = null;
    
    /**
     *入口文件
     * @var type 
     */
    public static $_entriesFile = '';
    
    /**
     *视图模板文件夹
     * @var type 
     */
    public static $_template = '';
    
    /**
     * 视图扩展名
     * @var string
     */
    private static $_extend='.php';
    private static $_instance = null;
    private $_var = array();
    
/*    public function render($controller,$action){
        foreach ($this->_var as $k=>$v){
            ${$k}=$v;
        }
        $file = APP_DIR.'view'.DS.$controller.DS.$action.self::$_extend;
        if(is_file($file)){
            include $file;
        }
    }*/
    
    private function __construct(){ }
    private function __clone(){ }
    
    public static function getInstance(){
    
        if (!self :: $_instance){
            self :: $_instance = new self();
            
            /**
             * 初始化模板路径
             */
            defined("APP_DIR") || define("APP_DIR",ROOT.'app'.DS);
            self :: $_instance ->  _dir = APP_DIR.'view'.DS;
        
            /**
             * 初始化js、css、img等网站素材所在目录
             */
            self :: $_instance -> updatePath();
        }
        
        return self :: $_instance;
    }
    
    /**
     * 初始化js、css、img等网站素材所在目录
     */
    public function updatePath(){
        self :: $_instance -> _www = defined("WEB_ROOT")?WEB_ROOT:'/'.str_replace(ROOT,'',APP_DIR).'/www/';
        self :: $_instance -> _uploadPath = '/uploads/pic/';
    }


    public function assign(){
        switch (func_num_args()){
            case 1:
                if(is_array(func_get_arg(0))){
                    foreach(func_get_arg(0) as $fun_key=>$fun_val){
                        $this->_var[$fun_key] = $fun_val;
                    }
                }
                break;
            case 2:
                $this->_var[func_get_arg(0)] = func_get_arg(1);
                break;
        }
    }

    public function getVar($key){
        if ($this->_var[$key] != ''){
            return $this->_var[$key];
        }
    }

    public function setVar($key,$value){
        return $this->_var[$key] = $value;
    }
    
    public function getAllVar(){
        return $this->_var;
    }
    
    public function htmlType(){
        $html_type = Bic_Router::getType();
        return $html_type=='normal'?'?':'';
    }
    
    /**
     * url链接生成
     * @uses	
     * @param $controller_view Controller/Action
     * @param $var 路由中的变量
     * @param $option 额外配置
     *
                'ajax_open'=>true,
                'ajax_func'=>'get_page',
                *
                 * 定义url参数
                 *  即第一个参数
                 *
                'ajax_url_parame'=>'',
                *
                 * 系统默认会添加参数：
                 *  第一个及第二个参数都是系统默认的:
                 *  url,page
                 *
                'ajax_parame'=>'true'
     * @return string
     */
    public function url(){
        $uri = '';
        $controller_view = func_get_arg(0);
        $var = func_num_args()>1?(is_array(func_get_arg(1))?func_get_arg(1):array()):array();
        $option = func_num_args()>2?func_get_arg(2):null;
        if($option['debug']){
            debug('路由变量一：');
            debug($controller_view);
            debug('路由变量二：');
            debug($var);
            debug('路由变量三：');
            debug($option);
            exit;
        }
        //debug(Bic_Router::getRoutes());
        $routers = Bic_Router::getRoutes();
        foreach ($routers as $router_val) {
            $url = str_replace('*','',$router_val['route']);
            if ($router_val['default']['controller'] . '/' . $router_val['default']['action'] == $controller_view) {
                $route = str_replace(array(':controller',':action'),'',$router_val['route']);
                preg_match_all('/'.Bic_Router::getUrlVariableDelimiter().'('.Bic_Router::getDefaultRouteParamReg().')/', $route,$match);
                if (count(array_diff_key($var,array_flip($match[1]))) == 0){
                    $option = is_array($option) ? array_merge($option, $router_val['default']) : $router_val['1'];
                    //计算路由变量 
                    foreach ($var as $con_k => $con_v) {
                        $url = str_replace(Bic_Router::getUrlVariableDelimiter() . $con_k, $con_v, $url);
                    }
                    $url = (str_replace(Bic_Router::getUrlDelimiter() . Bic_Router::getUrlDelimiter(), Bic_Router::getUrlDelimiter(), $url));
                    if (Bic_Router::getType() == 'normal') {
                        $url = trim($url, Bic_Router::getUrlDelimiter());
                        $url = "/" . self::$_entriesFile . ($url != '' ? '?' : '') . $url;
                    }
                    if ($router_val['option']['suffix']) {
                        $url.=Bic_Router::$_suffix;
                    }
                    $uri = ($this->host . (substr($url, 0, 1) == '/' ? '' : '/') . $url);
                    break;
                }
            }
        }
        
        //生成默认链接
        if (empty($uri)) {
            list($controller, $action) = explode('/', $controller_view);
            $uri = strtolower($controller) . Bic_Router::getUrlDelimiter() . $action ;
            //Bic_Router::getUrlDelimiter()) . join(Bic_Router::getUrlDelimiter(), $var)
            foreach ($var as $key => $val){
                $uri .= Bic_Router::getUrlDelimiter() . $key . Bic_Router::getUrlDelimiter() . $val;
            }
            if ($option['suffix']){
                $uri .= Bic_Router::$_suffix;
            }elseif (!isset($option['suffix']) && $router_val['option']['suffix']){
                $uri .= Bic_Router::$_suffix;
            }
        }

        /** ajax 配置 */
        if ($option['ajax']['ajax_open'] === true){
            $uri = $option['ajax']['ajax_url_parame']!=''?$option['ajax']['ajax_url_parame']:$uri;
            $page = $var[$option['ajax']['ajax_page_name']];
            unset($var[$option['ajax']['ajax_page_name']]);
            if ($option['ajax']['ajax_parame'] != ''){
                $ajax_parame = ",{$option['ajax']['ajax_parame']}";
            }
            if (count($var) > 0){
                $ajax_parame .= ",".implode(',', $var);
            }
            return "javascript:{$option['ajax']['ajax_func']}(\"{$uri}\"{$ajax_parame})";
        }else{
            //没有匹配的,返回‘#’
            return $uri!=''?$uri:'#';
        }
    }
    
    /**
     * 获取当前链接
     * @param $cover	要覆盖的字段。如：array('lg'=>'en')那么，变量lg的值将用en来替换
     * 					如果里面的值为array，如array('lg'=>array('type'=>'GET',)):那么，变量lg的值将用$_GET['lg']的来替换(当然，用GET是没有实际意义的)
     * 										如array('lg'=>array('type'=>'fun','name'=>'getValue','param'=>'5')):那么，将调用函数getValue,参数为5的结果，作为变量lg的值
     * @param $ext_con	扩展选项。即url函数的第三个参数
     * @return string
     */
    public function currentUrl($cover,$ext_con){
        $router = Bic_Router::getCurrentRoute();
        
        $cover = $cover==''?array():$cover;
        $ext_con = $ext_con==''?array():$ext_con;
        array_merge($router[3],$ext_con);
        $ext_con = $router[3];
        
        foreach($router[2] as $key => $val){
            $param[$key] = $_GET[$key];
        }
        foreach ($cover as $cover_key => $cover_val){
            if (is_array($cover_val)){
                switch ($cover_val['type']){
                    case 'fun':
                        $param[$cover_key] = $cover_val['name']($cover_val['param']);
                        break;
                    default:
                        $param[$cover_key] = $_GET[$key];
                        break;
                }
            }else{
                $param[$cover_key] = $cover_val;
            }
        }
        return $this->url($router[1]['controller'].'/'.$router[1]['action'],$param,$ext_con);
    }

    public function isAjax(){
        $currentRoute = Bic_Router::getCurrentRoute();
        if ($currentRoute[1]['ajax']['ajax_open'] === true){
            return true;
        }
        return false;
    }

    /**
     *render the tpl file
     * @param type $file
     * @param type $useTpl
     * @return type
     * @throws Bic_Exception 
     */
    public function render($file,$useTpl=true){
        
        if (self :: $_instance ->  _dir) $tpl = self :: $_instance ->  _dir;
        
        //设置模板文件夹
        if ($useTpl) $tpl .= self::$_template.DS;
        
        $tpl .= $file;
        
        if(is_file($tpl)){
            /**
             * 注册视图已定义变量
             */
            foreach ($this->_var as $k=>$v){
                ${$k}=$v;
            }
            
            ob_start();
            require $tpl;
            $layout_content = ob_get_clean();
            /*
             * 布局方式
             * 布局方式，与普通的view相同，只是相当于一种形式
             * 如果使用的布局方式，
             * 那么就要定义三个变量:
             * $layout_header
             * $layout_content
             * $layout_footer
             */
            $layout = APP_DIR.'view'.DS.'layout'.DS.$this -> _layout;
            if ($this -> _layout && is_file($layout)){
                ob_start();
                $layout_content = require $layout;
                $layout_content = ob_get_clean();
            }
            return $layout_content;
        }else{
            //404
            //self::__404();
            throw new Bic_Exception("模板文件不存在:\n{$tpl}");
            self::outMsg("模板文件不存在:<br />{$tpl}");
        }
    }
    
    /**
     * 获取当前模板路径下的css
     * @param string $name	文件名
     * @param array $attribute	$attribute['path']--css路径。默认或未定义时为系统定义的www目录:/app/www/
     */
    public function getStyle($name,$attribute=array('path'=>'')){
        $path = $attribute['path']!=''?rtrim($attribute['path'],array('/','\\')):false;
        $path = $path?$path.'/':$this->_www;
        return "<link rel='stylesheet' href='{$path}{$name}' type='text/css' />\n";
    }
    
    /**
     * 获取当前模板路径下的js
     * @param string $name	JS文件名
     * @param array $path	$attribute['path']--JS路径。默认或未定义时为系统定义的www目录:/app/www/
     */
    public function getJavascript($name,$attribute){
        $path = !empty($attribute['path'])?rtrim($attribute['path'],array('/','\\')):false;
        $path = $path?$path.'/':$this->_www;
        return "<script type='text/javascript' src='{$path}{$name}'></script>\n";
    }
    
    /**
     * 获取当前模板路径下的js
     * getJavascript的匿名函数
     * @param string $name	JS文件名
     * @param array $path	JS路径。默认或未定义时为系统定义的www目录:/app/www/
     */
    public function getJs($name,$attribute=array()){
        return $this->getJavascript($name,$attribute);
    }
    
    public function setTemplate($tpl){
        self::$_template = $tpl;
        $this -> updatePath();
        return self::$_template;
    }
    
    public function getTemplate(){
        return self::$_template;
    }
    
    /**
     * 加载视图文件
     * 在视图文件中，可以用此函数加载同一程序内的视图文件。
     * e.g. $this->load('layout'.DS.'head.php');
     * @param $path 以APP_DIR为起始目录
     * @throws Bic_Exception
     */
    public function load($tplFile,$path=''){
        $file = $this->_dir.$path.$tplFile;
        if(is_file($file)){
            foreach ($this->_var as $k=>$v){
                ${$k}=$v;
            }
            include($file);
        }else{
            throw new Bic_Exception("模板文件不存在:\n{$file}");
        }
    }
    
    public function get($key){
        return $this->getVar($key);
    }
    public function __get($key){
        return $this->get($key);
    }


    /**
     * 错误模板
     * --默认加载错误文件app/www/errors/error.php
     *   如果上面的文件不存在，则直接加载系统错误文件：bic/lib/view/errors/error.php
     * --在指定$error_file的情况下，首先加载的还是app/www/errors/下的$error_file文件，
     *   如果不存在，则加载系统默认定义的错误文件：bic/lib/view/errors/$error_file。
     * 
     * @param string $error_file	错误定义文件
     * @throws Bic_Exception
     */
    public function __error($error_file=null){
        $error_file = $error_file!=''?$error_file:'error.php';
        if (!is_file($file = $this->_dir.'errors'.DS.$error_file)){
            if (is_file(LIB.'view'.DS.'errors'.DS.$error_file)){
                $this->_dir = LIB.'view'.DS.'errors'.DS;
                $file = $error_file;
            }else{
                die("请手动定义错误文件'error/error.php':\n或者请不要删除系统错误文件：{$file}");
                
            }
        }
        echo $this->render($file,false);
        exit;
    }
}

